home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
276-300
/
299
/
rxil
/
src
/
launch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-14
|
5KB
|
244 lines
/* launch.c */
/* Copyright © 1989 by Donald T. Meyer, Stormgate Software
* All Rights Reserved
*/
#include "rxil.h"
#include <string.h>
/* NAME
* RxilLaunch
*
* SYNOPSIS
* result = RxilLaunch( rxi )
*
* LONG result;
*
* struct RxilInvocation *rxi;
*
* FUNCTION
* Launch an ARexx program by sending an invocation message
* to the RexxMaster process. The RxilInvocation structure
* which is allocated prior to this call via RxilCreateRxi()
* contains the information neccessary to launch the program.
*
* INPUTS
* rxi A pointer to an initialized RxilInvocation structure.
*
* RESULT
* Zero if the launch was successful, non-zero otherwise.
*
* SIDES
*
* HISTORY
* 01-Aug-89 Creation.
*
* BUGS
*
* SEE ALSO
* RxilCreateRxi(), RxilDeleteRxi()
*/
LONG RxilLaunch( struct RxilInvocation *rxi )
{
struct RexxArg *arg;
struct MsgPort *rmast, *replyport;
struct RexxMsg *rexxmsg;
int i;
int ac=0;
UWORD len;
/* Make call "safe" even if RxilInit() failed */
if( global_rdef == NULL )
{
return( -1 );
}
/* Replys can come in at either port. */
replyport = global_rdef->SecretPort ?
global_rdef->SecretPort : global_rdef->PublicPort;
if( rxi->State != RXIL_STATE_AVAILABLE )
{
/* A command is already launched, (using this structure),
* or the reply has not yet been dealt with.
*/
return( -1 );
}
/* Allocate a packet to send to rexxmaster */
rexxmsg = CreateRexxMsg( replyport, rxi->FileExt, rxi->CommAddr );
if( rexxmsg == NULL )
{
return( -1 );
}
/* Allocate an argument string for the command name and args */
arg = CreateArgstring( rxi->Name, strlen( rxi->Name ) );
if( arg == NULL )
{
DeleteRexxMsg( rexxmsg );
return( -1 );
}
ARG0(rexxmsg) = (STRPTR)arg;
if( rxi->Type == RXFUNC )
{
/* This is a Function invocation. */
/* Turn the arguments into Rexx Argstrings and place in the
* RexxMsg packet.
*/
for( i=1; i<=MAXRMARG; i++ )
{
if( rxi->FuncArg[i] == NULL )
{
/* Empty argument slot, consider it the last */
break;
}
/* We can either determine the argument length, or the client
* can pre-set a count.
*/
len = rxi->CountArgs ?
rxi->ArgLen[i] : strlen(rxi->FuncArg[i]);
rexxmsg->rm_Args[i] =
(STRPTR)CreateArgstring( rxi->FuncArg[i], len );
ac++;
if( rexxmsg->rm_Args[i] == NULL )
{
/* Unable to create this argstring. Cleanup and return
* a failure code.
*/
for( i=0; i<=MAXRMARG; i++ )
{
if( rexxmsg->rm_Args[i] != NULL )
{
DeleteArgstring( (struct RexxArg *)
(rexxmsg->rm_Args[i]) );
}
}
DeleteRexxMsg( rexxmsg );
return( -1 );
}
}
rexxmsg->rm_Action = RXFUNC | rxi->ActionFlags | ac;
}
else
{
/* This is a Command invocation */
rexxmsg->rm_Action = RXCOMM | rxi->ActionFlags;
}
/* Set up the I/O streams for the macro */
if( rxi->Parent == NULL )
{
/* This is an original launch from the application */
if( rxi->Console )
{
/* And there is a console spec. Use it. */
RxilOpenConsole( rxi->Console, rexxmsg );
}
}
else
{
/* This is a loopback child of a macro. Use the I/O fields
* from the parent message.
*/
rexxmsg->rm_Stdin = rxi->Parent->rm_Stdin;
rexxmsg->rm_Stdout = rxi->Parent->rm_Stdout;
}
Forbid();
if( ( rmast = FindPort( rxi->IHostPort ) ) != NULL )
{
PutMsg( rmast, (struct message *)rexxmsg );
}
Permit();
if( rmast == NULL )
{
/* we could not find the REXX port, this failed!
* Cleanup and return a failure code.
*/
for( i=0; i<=MAXRMARG; i++ )
{
if( rexxmsg->rm_Args[i] != NULL )
{
DeleteArgstring( (struct RexxArg *)
(rexxmsg->rm_Args[i]) );
}
}
if( rxi->Console )
{
RxilCloseConsole( rexxmsg );
}
DeleteRexxMsg( rexxmsg );
return( -1 );
}
/* If we make it here, we have hopefully launched. */
/* Set this so we can recognize the reply, and to let us know that
* we have a command pending.
*/
rxi->RexxMsg = rexxmsg;
rxi->State = RXIL_STATE_PENDING;
if( rxi->CommAddr == global_rdef->SecretPortName )
{
#if 0
if( global_rdef->Locked )
{
/* Since we are locked, we should not be launching any macros
* which have the secret port as their initial host address.
*/
return( -1 );
}
#endif
/* Increment the locked count.
*/
global_rdef->LockCount++;
}
if( rxi->Parent == NULL )
{
/* This is a launch originated within the application. */
if( FlagIsClear( global_rdef->Flags, RXIL_NO_ABORT ) )
{
/* Post the macro cancel requester */
RxilPostCancel();
}
}
return( 0 );
}